﻿//==================================================================
// Copyright (C) 2015 福流网络
// 作 者：江怀玉
// 日 期：2015-04-22
// 描 述： 常用反射方法,用于动态创建实体类，以及动态获取/设置实体对象的属性值
// 版 本：1.00
// 修改历史纪录
// 版 本  修改时间      修改人            修改内容
//==================================================================
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FL.DBModule;
using FL.Lite;

namespace FL.Common
{
    /// <summary>
    /// 常用反射使用方法
    /// </summary>
    public class ClassField
    {
        public string cType
        {
            get;
            set;
        }

        public object Field
        {
            get;
            set;
        }

        public ClassField(string ctype, object field)
        {
            cType = ctype;
            Field = field;
        }
    }
    

    public class Reflection
    {
        /// <summary>
        /// 获取相关信息
        /// </summary>
        /// <returns></returns>
        public static SortedDictionary<string, object> ReaderAutoMapper(object obj)
        {
            //if (!(obj is BaseEntity))
            //{
            //    return new SortedDictionary<string, object>(); 
            //}

            SortedDictionary<string, object> ht = new SortedDictionary<string, object>();

            //　利用反射获类的属性名称和属性值　
            Type t = obj.GetType();
            PropertyInfo[] Mypropertyinfos = t.GetProperties();
            foreach (PropertyInfo pi in Mypropertyinfos)
            {
                try
                {
                    //if (!(obj is BaseEntity))
                    {
                        bool bl = false;
                        foreach (Attribute attr in pi.GetCustomAttributes(true))
                        {

                            ColumnAttribute tableattribute = attr as ColumnAttribute;
                            if (null != tableattribute)
                            {
                                bl=true;
                            }
                        }
                        if (!bl)
                        {
                            continue;
                        }
                    }
                    if (pi.Name.IndexOf("iSun_") == 0 || pi.Name == "BaseEntityState" || pi.Name == "IsGuid" || pi.PropertyType.FullName.IndexOf("System")<0)
                    {
                        continue;
                    }
                    
                    Object Value = t.InvokeMember(pi.Name,
                        BindingFlags.DeclaredOnly |
                        BindingFlags.Public | BindingFlags.NonPublic |
                        BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null);

                    ht.Add(pi.Name, Value);
                }
                catch (System.Exception e)
                {
                    //AppLog.Write(e.Message, AppLog.LogMessageType.Info);
                    //throw e;
                }

            }
            return ht;
        }

        public static SortedDictionary<string, ClassField> ReaderAutoMapper(BaseEntity obj)
        {
            SortedDictionary<string, ClassField> ht = new SortedDictionary<string, ClassField>();
            try
            {
                //　利用反射获类的属性名称和属性值　
                Type t = obj.GetType();
                PropertyInfo[] Mypropertyinfos = t.GetProperties();
                foreach (PropertyInfo pi in Mypropertyinfos)
                {
                    // 
                    Object Value = t.InvokeMember(pi.Name,
                        BindingFlags.DeclaredOnly |
                        BindingFlags.Public | BindingFlags.NonPublic |
                        BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null);
                    if (pi.Name.IndexOf("iSun_") == 0)
                    {
                        continue;
                    }
                    string cType = Value.GetType().ToString();
                    if (Value is DateTime)
                    {
                        cType = "DT";
                    }


                    ht.Add(pi.Name, new ClassField(cType, Value));
                }
            }
            catch (System.Exception e)
            {
                //AppLog.Write(e.Message, AppLog.LogMessageType.Info);
                throw e;
            }
            return ht;
        }

        /// <summary>
        /// 实例化类
        /// </summary>
        /// <param name="ClassName">类名</param>
        /// <returns>实例对象</returns>
        public static object CreateEntitysInstance(string TypeName)
        {
            IList<FL.DBModule.Sys.t_sys_lib> list = BaseEntity.GetList<FL.DBModule.Sys.t_sys_lib>("t_sys_lib", "type='e'");
            object entitys = null;
            if (list != null)
            {
                foreach (FL.DBModule.Sys.t_sys_lib lib in list)
                {
                    try
                    {
                        entitys = CreateInstance(lib.name + "." + TypeName, string.IsNullOrEmpty(lib.assembly_name)?lib.name:lib.assembly_name);
                    }
                    catch { }
                    if (entitys != null)
                    {
                        return entitys;
                    }
                }
            }
            return entitys;
        }


        /// <summary>
        /// 创建实例
        /// </summary>
        /// <param name="TypeName">类型名</param>
        /// <param name="AssemblyName">动态库命</param>
        /// <returns>实例对象</returns>
        public static object CreateInstance(string TypeName, string AssemblyName)
        {
            Assembly assem = Assembly.Load(AssemblyName);
            object obj = CreateInstance(TypeName, assem);
            return obj;
        }

        /// <summary>
        /// 创建实例
        /// </summary>
        /// <param name="TypeName">类型名</param>
        /// <param name="assembly">动态库</param>
        /// <returns>实例对象</returns>
        public static object CreateInstance(string TypeName, Assembly assembly)
        {
            try
            {
                Type t = assembly.GetType(TypeName);
                if (t == null)
                {
                    t = assembly.GetType(assembly.GetName().Name + "." + TypeName);
                }
                object obj = Activator.CreateInstance(t);
                return obj;
            }
            catch (System.Exception e)
            {
                throw e;
            }

        }
    }
}
